package org.x.casemodule.service.Impl;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import org.x.casemodule.dto.*;
import org.x.casemodule.entity.*;
import org.x.casemodule.enums.*;
import org.x.casemodule.mapper.*;
import org.x.casemodule.service.ScheduleService;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ScheduleServiceImpl implements ScheduleService {

    @Resource
    private ScheduleEventMapper scheduleEventMapper;

    @Resource
    private ScheduleParticipantMapper scheduleParticipantMapper;

    @Resource
    private ScheduleReminderMapper scheduleReminderMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ScheduleCreateResponse createSchedule(ScheduleCreateRequest request) {
        // 1. 创建日程事件
        ScheduleEventEntity event = new ScheduleEventEntity();
        event.setTitle(request.getTitle());
        event.setType(request.getEventType()); // 直接使用枚举类型
        event.setStartTime(request.getStartTime());
        event.setEndTime(request.getEndTime());
        event.setLocation(request.getLocation());
        event.setCreatorId(request.getCreatorId());
        event.setCaseId(request.getCaseId());
        event.setCreateTime(new Date());
        event.setUpdateTime(new Date());
        event.setStatus(EventStatus.ACTIVE); // 使用枚举类型
        event.setIsLocked(0);

        scheduleEventMapper.insert(event);

        // 2. 创建参与者
        if (request.getParticipants() != null && !request.getParticipants().isEmpty()) {
            for (Long participantId : request.getParticipants()) {
                ScheduleParticipantEntity participant = new ScheduleParticipantEntity();
                participant.setEventId(event.getId());
                participant.setUserId(participantId);
                participant.setRole(RoleEnum.ATTENDEE); // 使用枚举类型
                participant.setResponseStatus(ResponseStatusEnum.getByCode("ACCEPTED")); // 使用枚举类型

                scheduleParticipantMapper.insert(participant);
            }
        }

        // 3. 创建提醒
        if (request.getReminder() != null && request.getReminder().getMethods() != null) {
            for (MethodEnum method : request.getReminder().getMethods()) {  // 修改遍历方式
                ScheduleReminderEntity reminder = new ScheduleReminderEntity();
                reminder.setEventId(event.getId());
                reminder.setAdvanceMinutes(request.getReminder().getAdvanceMinutes() != null ?
                        request.getReminder().getAdvanceMinutes() : 30);
                reminder.setMethod(method); // 直接使用MethodEnum

                // 计算触发时间
                if (request.getStartTime() != null && request.getReminder().getAdvanceMinutes() != null) {
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(request.getStartTime());
                    calendar.add(Calendar.MINUTE, -request.getReminder().getAdvanceMinutes());
                    reminder.setTriggerTime(calendar.getTime());
                }

                reminder.setStatus(ReminderStatusEnum.PENDING);

                scheduleReminderMapper.insert(reminder);
            }
        }


        // 4. 检查冲突 - 查询数据库中与当前事件时间重叠的事件
        List<ScheduleCreateResponse.ConflictInfo> conflicts = new ArrayList<>();

        // 只有当需要检查冲突且必要参数存在时才进行检查
        if (request.getCheckConflict() != null && request.getCheckConflict() &&
                request.getCreatorId() != null &&
                request.getStartTime() != null &&
                request.getEndTime() != null) {

            List<ScheduleEventEntity> conflictingEvents = scheduleEventMapper.findConflictingEvents(
                    request.getCreatorId(),
                    request.getStartTime(),
                    request.getEndTime()
            );

            // 将冲突事件转换为ConflictInfo对象
            for (ScheduleEventEntity conflictingEvent : conflictingEvents) {
                // 跳过自己
                if (conflictingEvent.getId().equals(event.getId())) {
                    continue;
                }

                ScheduleCreateResponse.ConflictInfo conflictInfo = new ScheduleCreateResponse.ConflictInfo();
                conflictInfo.setEventId("EVENT" + conflictingEvent.getId());
                conflictInfo.setTitle(conflictingEvent.getTitle());
                conflictInfo.setEventType(conflictingEvent.getType());
                conflictInfo.setStartTime(conflictingEvent.getStartTime());
                conflictInfo.setEndTime(conflictingEvent.getEndTime());
                conflictInfo.setConflictType(determineConflictType(event, conflictingEvent));
                conflicts.add(conflictInfo);
            }
        }

        // 5. 构造响应
        ScheduleCreateResponse response = new ScheduleCreateResponse();
        String eventId = "EVENT" + event.getId();
        response.setEventId(eventId);
        response.setConflicts(conflicts); // 使用实际检测到的冲突

        return response;
    }

    /**
     * 确定冲突类型
     */
    private String determineConflictType(ScheduleEventEntity newEvent, ScheduleEventEntity existingEvent) {
        if (newEvent.getStartTime().before(existingEvent.getStartTime()) &&
                newEvent.getEndTime().after(existingEvent.getEndTime())) {
            return "完全包含";
        } else if (newEvent.getStartTime().after(existingEvent.getStartTime()) &&
                newEvent.getEndTime().before(existingEvent.getEndTime())) {
            return "被包含";
        } else if (newEvent.getStartTime().equals(existingEvent.getStartTime()) &&
                newEvent.getEndTime().equals(existingEvent.getEndTime())) {
            return "完全重叠";
        } else {
            return "部分重叠";
        }
    }







    @Override
    @Transactional(rollbackFor = Exception.class)
    public ScheduleCreateResponse updateSchedule(ScheduleUpdateRequest request) {
        // 1. 查找现有事件
        ScheduleEventEntity event = scheduleEventMapper.selectOneById(request.getEventId());
        if (event == null) {
            throw new RuntimeException("未找到指定的日程事件");
        }

        // 2. 更新事件基本信息
        event.setTitle(request.getTitle());
        event.setType(request.getEventType());
        event.setStartTime(request.getStartTime());
        event.setEndTime(request.getEndTime());
        event.setLocation(request.getLocation());
        event.setCaseId(request.getCaseId());
        event.setUpdateTime(new Date());

        scheduleEventMapper.update(event);

        // 3. 更新参与者信息（先删除再重新添加）
        if (request.getParticipants() != null) {
            // 删除原有参与者
            scheduleParticipantMapper.deleteByEventId(event.getId());

            // 添加新参与者
            for (Long participantId : request.getParticipants()) {
                ScheduleParticipantEntity participant = new ScheduleParticipantEntity();
                participant.setEventId(event.getId());
                participant.setUserId(participantId);
                participant.setRole(RoleEnum.ATTENDEE);
                participant.setResponseStatus(ResponseStatusEnum.ACCEPTED);

                scheduleParticipantMapper.insert(participant);
            }
        }

// 4. 更新提醒信息（先删除再重新添加）
        if (request.getReminder() != null) {
            // 删除原有提醒
            scheduleReminderMapper.deleteByEventId(event.getId());

            // 添加新提醒
            if (request.getReminder().getMethods() != null) {
                for (MethodEnum method : request.getReminder().getMethods()) {
                    ScheduleReminderEntity reminder = new ScheduleReminderEntity();
                    reminder.setEventId(event.getId());
                    reminder.setAdvanceMinutes(request.getReminder().getAdvanceMinutes() != null ?
                            request.getReminder().getAdvanceMinutes() : 30);
                    reminder.setMethod(method);

                    // 计算触发时间
                    if (request.getStartTime() != null && request.getReminder().getAdvanceMinutes() != null) {
                        Calendar calendar = Calendar.getInstance();
                        calendar.setTime(request.getStartTime());
                        calendar.add(Calendar.MINUTE, -request.getReminder().getAdvanceMinutes());
                        reminder.setTriggerTime(calendar.getTime());
                    }

                    reminder.setStatus(ReminderStatusEnum.PENDING);
                    scheduleReminderMapper.insert(reminder);
                }
            }
        }



        // 5. 检查冲突
        List<ScheduleCreateResponse.ConflictInfo> conflicts = new ArrayList<>();

        if (request.getCheckConflict() != null && request.getCheckConflict() &&
                event.getCreatorId() != null &&
                request.getStartTime() != null &&
                request.getEndTime() != null) {

            List<ScheduleEventEntity> conflictingEvents = scheduleEventMapper.findConflictingEvents(
                    event.getCreatorId(),
                    request.getStartTime(),
                    request.getEndTime()
            );

            // 将冲突事件转换为ConflictInfo对象
            for (ScheduleEventEntity conflictingEvent : conflictingEvents) {
                // 跳过自己
                if (conflictingEvent.getId().equals(event.getId())) {
                    continue;
                }

                ScheduleCreateResponse.ConflictInfo conflictInfo = new ScheduleCreateResponse.ConflictInfo();
                conflictInfo.setEventId("EVENT" + conflictingEvent.getId());
                conflictInfo.setTitle(conflictingEvent.getTitle());
                conflictInfo.setEventType(conflictingEvent.getType());
                conflictInfo.setStartTime(conflictingEvent.getStartTime());
                conflictInfo.setEndTime(conflictingEvent.getEndTime());
                conflictInfo.setConflictType(determineConflictType(event, conflictingEvent));
                conflicts.add(conflictInfo);
            }
        }

        // 6. 构造响应
        ScheduleCreateResponse response = new ScheduleCreateResponse();
        String eventId = "EVENT" + event.getId();
        response.setEventId(eventId);
        response.setConflicts(conflicts);

        return response;
    }



    // 添加到 ScheduleServiceImpl.java 中
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSchedule(Long eventId) {
        // 1. 删除事件相关的参与者信息
        scheduleParticipantMapper.deleteByEventId(eventId);

        // 2. 删除事件相关的提醒信息
        scheduleReminderMapper.DeleteByEventId(eventId);

        // 3. 删除事件本身
        scheduleEventMapper.deleteById(eventId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CourtScheduleResponse shareCourtSchedule(CourtScheduleRequest request) {
        try {
            log.info("开始处理法院日程共享请求: {}", request);

            // 1. 创建日程事件
            ScheduleEventEntity event = new ScheduleEventEntity();
            event.setTitle(request.getCaseNumber() + " - " + request.getJudge());
            event.setType(EventType.COURT); // 法院事件类型

            // 直接使用传入的Date对象，无需解析
            event.setStartTime(request.getStartTime());
            event.setEndTime(request.getEndTime());

            event.setLocation(request.getCourt() + " " + request.getRoom());
            event.setCreatorId(1L); // 默认创建者ID，实际应从上下文获取
            event.setCaseId(request.getCaseId()); // 直接使用Long类型的caseId

            event.setCreateTime(new Date());
            event.setUpdateTime(new Date());
            event.setStatus(EventStatus.ACTIVE);
            event.setIsLocked(1); // 法院事件锁定，不可修改

            // 设置法院信息
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> courtInfo = new HashMap<>();
            courtInfo.put("court", request.getCourt());
            courtInfo.put("room", request.getRoom());
            courtInfo.put("judge", request.getJudge());
            courtInfo.put("caseNumber", request.getCaseNumber());
            courtInfo.put("courtEventId", request.getCourtEventId());
            courtInfo.put("caseId", request.getCaseId());

            try {
                String courtInfoJson = objectMapper.writeValueAsString(courtInfo);
                event.setCourtInfo(courtInfoJson);
            } catch (JsonProcessingException e) {
                log.error("法院信息序列化失败", e);
                throw new RuntimeException("法院信息处理失败");
            }

            scheduleEventMapper.insert(event);
            log.info("成功插入事件，ID: {}", event.getId());

            // 2. 创建参与者
            if (request.getParticipants() != null && !request.getParticipants().isEmpty()) {
                for (Object participantObj : request.getParticipants()) {
                    Long participantId = null;

                    // 处理传入的是字符串（名称）还是Long（ID）的情况
                    if (participantObj instanceof String) {
                        // 如果是字符串，需要转换为用户ID
                        String participantName = (String) participantObj;
                        log.warn("需要实现根据用户名称'{}'查找用户ID的逻辑", participantName);
                        // 可以使用默认ID或者跳过处理
                    } else if (participantObj instanceof Long) {
                        participantId = (Long) participantObj;
                    } else if (participantObj instanceof Integer) {
                        participantId = ((Integer) participantObj).longValue();
                    }

                    ScheduleParticipantEntity participant = new ScheduleParticipantEntity();
                    participant.setEventId(event.getId());
                    participant.setUserId(participantId != null ? participantId : 0L); // 使用默认ID或实际ID
                    participant.setRole(RoleEnum.ATTENDEE);
                    participant.setResponseStatus(ResponseStatusEnum.getByCode("ACCEPTED"));

                    scheduleParticipantMapper.insert(participant);
                }
            }

            // 3. 构造响应
            CourtScheduleResponse response = new CourtScheduleResponse();
            response.setEventId("COURT" + new SimpleDateFormat("yyyyMMdd").format(new Date()) +
                    String.format("%03d", event.getId() % 1000));
            response.setSyncStatus("SYNCED");
            response.setCourtSystemRef(request.getCourtEventId());

            log.info("返回响应: {}", response);
            return response;

        } catch (Exception e) {
            log.error("处理法院日程共享请求时发生错误: {}", e.getMessage(), e);
            throw new RuntimeException("处理法院日程共享请求失败: " + e.getMessage(), e);
        }
    }








    // 视图
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> getView(String view, String date, Boolean includeShared) {
        // 解析日期参数
        Date currentDate = parseDate(date);

        // 根据视图类型确定时间范围
        Map<String, Object> dateRange = getDateRange(view, currentDate);

        // 查询事件
        List<ScheduleEventEntity> events = queryEvents(view, dateRange, includeShared);

        // 转换为响应格式
        List<Map<String, Object>> formattedEvents = formatEvents(events);

        // 构造响应
        Map<String, Object> result = new HashMap<>();
        result.put("viewType", view.toUpperCase());
        result.put("dateRange", dateRange);
        result.put("events", formattedEvents);

        return result;
    }

    private Date parseDate(String dateStr) {
        if (dateStr == null || dateStr.isEmpty()) {
            return new Date();
        }
        try {
            return new SimpleDateFormat("yyyy-MM-dd").parse(dateStr);
        } catch (ParseException e) {
            log.warn("日期解析失败: {}", dateStr);
            return new Date();
        }
    }

    private Map<String, Object> getDateRange(String view, Date date) {
        Map<String, Object> range = new HashMap<>();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        switch (view.toLowerCase()) {
            case "day":
                // 设置当天的开始和结束时间
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                Date startOfDay = calendar.getTime();

                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                calendar.set(Calendar.MILLISECOND, 999);
                Date endOfDay = calendar.getTime();

                range.put("start", startOfDay);
                range.put("end", endOfDay);
                break;

            case "week":
                // 设置本周的开始和结束时间
                int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
                // 周一为一周的开始
                calendar.add(Calendar.DAY_OF_WEEK, -dayOfWeek + 1);
                Date startOfWeek = calendar.getTime();

                calendar.add(Calendar.DAY_OF_WEEK, 6);
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                calendar.set(Calendar.MILLISECOND, 999);
                Date endOfWeek = calendar.getTime();

                range.put("start", startOfWeek);
                range.put("end", endOfWeek);
                break;

            case "month":
                // 设置本月的开始和结束时间
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.set(Calendar.MINUTE, 0);
                calendar.set(Calendar.SECOND, 0);
                calendar.set(Calendar.MILLISECOND, 0);
                Date startOfMonth = calendar.getTime();

                calendar.add(Calendar.MONTH, 1);
                calendar.add(Calendar.DAY_OF_MONTH, -1);
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                calendar.set(Calendar.MILLISECOND, 999);
                Date endOfMonth = calendar.getTime();

                range.put("start", startOfMonth);
                range.put("end", endOfMonth);
                break;

            default:
                throw new IllegalArgumentException("不支持的视图类型: " + view);
        }

        return range;
    }

    private List<ScheduleEventEntity> queryEvents(String view, Map<String, Object> dateRange, Boolean includeShared) {
        Date startTime = (Date) dateRange.get("start");
        Date endTime = (Date) dateRange.get("end");

        // 根据视图类型和时间范围查询事件
        List<ScheduleEventEntity> events = scheduleEventMapper.findEventsByTimeRange(startTime, endTime);

        // 如果需要包含共享事件，则查询共享表
        if (includeShared != null && includeShared) {
            // 这里需要实现查询共享事件的逻辑
            // 可能需要关联 schedule_share 表
            List<ScheduleEventEntity> sharedEvents = querySharedEvents(startTime, endTime);
            events.addAll(sharedEvents);
        }

        return events;
    }

    private List<ScheduleEventEntity> querySharedEvents(Date startTime, Date endTime) {
        // 实际应用中应该从安全上下文中获取当前用户ID
        Long currentUserId = 1L; // 模拟当前用户ID
        return scheduleEventMapper.findSharedEventsByTimeRange(currentUserId, startTime, endTime);
    }

    private List<Map<String, Object>> formatEvents(List<ScheduleEventEntity> events) {
        List<Map<String, Object>> formattedEvents = new ArrayList<>();

        // 实际应用中应该从安全上下文中获取当前用户ID
        Long currentUserId = 1L; // 模拟当前用户ID

        for (ScheduleEventEntity event : events) {
            Map<String, Object> formattedEvent = new HashMap<>();

            formattedEvent.put("eventId", "EVENT" + event.getId());
            formattedEvent.put("title", event.getTitle() != null ? event.getTitle() : "");
            formattedEvent.put("eventType", event.getType() != null ? event.getType().getCode() : "");
            formattedEvent.put("startTime", event.getStartTime());
            formattedEvent.put("endTime", event.getEndTime());
            formattedEvent.put("location", event.getLocation() != null ? event.getLocation() : "");
            formattedEvent.put("caseId", event.getCaseId());

            // 获取提醒信息
            try {
                List<ScheduleReminderEntity> reminders = scheduleReminderMapper.findByEventId(event.getId());
                if (reminders != null && !reminders.isEmpty()) {
                    Map<String, Object> reminderInfo = new HashMap<>();
                    reminderInfo.put("triggerTime", reminders.get(0).getTriggerTime());
                    reminderInfo.put("methods", reminders.stream()
                            .map(r -> {
                                if (r.getMethod() != null) {
                                    return r.getMethod().getCode();
                                }
                                return "";
                            })
                            .collect(Collectors.toList()));
                    formattedEvent.put("reminder", reminderInfo);
                }
            } catch (Exception e) {
                log.warn("获取事件 {} 的提醒信息失败: {}", event.getId(), e.getMessage());
            }

            // 判断是否为共享事件
            boolean isShared = false;
            if (event.getCreatorId() != null && !event.getCreatorId().equals(currentUserId)) {
                isShared = true;
            }
            formattedEvent.put("isShared", isShared);

            formattedEvents.add(formattedEvent);
        }

        return formattedEvents;
    }





    // 在 ScheduleServiceImpl.java 中添加以下代码
    //日程共享
    @Resource
    private ScheduleShareMapper scheduleShareMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ScheduleShareResponse shareSchedule(ScheduleShareRequest request) {
        // 1. 解析过期时间
        Date expireTime = null;
        if (request.getExpireTime() != null && !request.getExpireTime().isEmpty()) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
                expireTime = sdf.parse(request.getExpireTime());
            } catch (ParseException e) {
                log.error("过期时间解析失败", e);
                throw new RuntimeException("过期时间格式错误");
            }
        }

        // 2. 获取权限枚举
        // 2. 获取权限枚举
        PermissionEnum permission = request.getPermission();
        if (permission == null) {
            throw new RuntimeException("权限级别不能为空");
        }


        // 3. 生成共享ID
        String shareId = "SHARE" + new SimpleDateFormat("yyyyMMdd").format(new Date()) +
                String.format("%03d", System.currentTimeMillis() % 1000);

        // 4. 创建共享记录
        List<ScheduleShareResponse.SharedEvent> sharedEvents = new ArrayList<>();

        for (String eventIdStr : request.getEventIds()) {
            // 从事件ID字符串中提取数字ID
            Long eventId = extractEventId(eventIdStr);

            // 检查事件是否存在
            ScheduleEventEntity event = scheduleEventMapper.selectOneById(eventId);
            if (event == null) {
                log.warn("事件不存在: eventId={}", eventId);
                continue;
            }

            ScheduleShareResponse.SharedEvent sharedEvent = new ScheduleShareResponse.SharedEvent();
            sharedEvent.setEventId(eventIdStr);

            List<ScheduleShareResponse.SharedEvent.TargetUser> targetUsers = new ArrayList<>();

            // 为每个目标用户创建共享记录
            for (Long userId : request.getTargetUserIds()) {
                // 检查是否已存在相同的共享记录
                QueryWrapper queryWrapper = QueryWrapper.create()
                        .where("event_id = ?", eventId)
                        .and("from_user_id = ?", event.getCreatorId())
                        .and("to_user_id = ?", userId);

                log.debug("查询共享记录的SQL: {}", queryWrapper.toSQL());
                log.debug("查询参数: eventId={}, fromUserId={}, toUserId={}", eventId, event.getCreatorId(), userId);

                ScheduleShareEntity existingShare = scheduleShareMapper.selectOneByQuery(queryWrapper);



                ScheduleShareEntity shareEntity;
                if (existingShare != null) {
                    // 更新现有记录
                    shareEntity = existingShare;
                    shareEntity.setPermission(permission);
                    shareEntity.setExpireTime(expireTime);
                    shareEntity.setCreateTime(new Date());
                    scheduleShareMapper.update(shareEntity);
                } else {
                    // 创建新记录
                    shareEntity = new ScheduleShareEntity();
                    shareEntity.setEventId(eventId);
                    shareEntity.setFromUserId(event.getCreatorId()); // 当前用户为共享者
                    shareEntity.setToUserId(userId);
                    shareEntity.setPermission(permission);
                    shareEntity.setShareToken(generateShareToken()); // 生成共享令牌
                    shareEntity.setExpireTime(expireTime);
                    shareEntity.setCreateTime(new Date());
                    scheduleShareMapper.insert(shareEntity);
                }

                // 构造响应数据
                ScheduleShareResponse.SharedEvent.TargetUser targetUser =
                        new ScheduleShareResponse.SharedEvent.TargetUser();
                targetUser.setUserId(userId);
                targetUser.setStatus("PENDING");
                targetUsers.add(targetUser);
            }

            sharedEvent.setTargetUsers(targetUsers);
            sharedEvents.add(sharedEvent);
        }

        // 5. 构造响应
        ScheduleShareResponse response = new ScheduleShareResponse();
        response.setShareId(shareId);
        response.setSharedEvents(sharedEvents);

        return response;
    }

    // 辅助方法：从事件ID字符串中提取数字ID
    private Long extractEventId(String eventIdStr) {
        if (eventIdStr == null || eventIdStr.isEmpty()) {
            throw new RuntimeException("事件ID不能为空");
        }

        // 假设事件ID格式为 "EVENT20240515001" 或 "COURT20240515001"
        // 提取数字部分
        String numericPart = eventIdStr.replaceAll("[^0-9]", "");
        if (numericPart.isEmpty()) {
            throw new RuntimeException("无效的事件ID格式: " + eventIdStr);
        }
        return Long.valueOf(numericPart);
    }

    // 辅助方法：生成共享令牌
    private String generateShareToken() {
        // 生成随机令牌
        return UUID.randomUUID().toString().replace("-", "").toUpperCase();
    }






    // 在类中添加ScheduleSyncMapper的注入
    @Resource
    private ScheduleSyncMapper scheduleSyncMapper;

    // 在类中添加以下方法
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ScheduleSyncResponse syncExternalCalendar(ScheduleSyncRequest request) {
        // 1. 验证请求参数
        validateSyncRequest(request);

        // 2. 获取用户信息 (模拟实现，实际应从上下文获取)
        Long userId = 1L; // 实际应从SecurityContext或Token中获取

        // 3. 创建同步会话
        String syncSessionId = createSyncSession(request, userId);

        // 4. 执行同步操作
        ScheduleSyncResponse.SyncStats stats = executeSyncOperation(request, syncSessionId, userId);

        // 5. 计算下次同步时间
        String nextSyncTime = calculateNextSyncTime();

        // 6. 构造响应
        ScheduleSyncResponse response = new ScheduleSyncResponse();
        response.setSyncSessionId(syncSessionId);
        response.setStats(stats);
        response.setNextSyncTime(nextSyncTime);

        return response;
    }

    private void validateSyncRequest(ScheduleSyncRequest request) {
        if (request.getPlatform() == null) {
            throw new IllegalArgumentException("平台类型不能为空");
        }

        if (request.getAuthToken() == null || request.getAuthToken().isEmpty()) {
            throw new IllegalArgumentException("认证令牌不能为空");
        }

        if (request.getSyncDirection() == null) {
            throw new IllegalArgumentException("同步方向不能为空");
        }

        // 验证平台是否支持
        if (!Arrays.asList(PlatformEnum.GOOGLE, PlatformEnum.OUTLOOK, PlatformEnum.COURT_SYSTEM)
                .contains(request.getPlatform())) {
            throw new IllegalArgumentException("不支持的平台类型: " + request.getPlatform());
        }
    }

    private String createSyncSession(ScheduleSyncRequest request, Long userId) {
        // 生成同步会话ID
        String syncSessionId = "SYNC" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) +
                String.format("%03d", new Random().nextInt(1000));

        // 创建同步记录
        ScheduleSyncEntity syncEntity = new ScheduleSyncEntity();
        syncEntity.setUserId(userId);
        syncEntity.setPlatform(request.getPlatform());
        syncEntity.setSyncDirection(request.getSyncDirection());
        // 如果数据库字段是JSON类型，需要存储为JSON格式
        syncEntity.setAuthToken("\"" + encryptToken(request.getAuthToken()) + "\""); // 加密存储并加上引号
        syncEntity.setLastSyncStatus("PENDING");
        syncEntity.setCreateTime(new Date());
        syncEntity.setLastSyncTime(new Date());
        syncEntity.setSyncSessionId(syncSessionId);

        scheduleSyncMapper.insert(syncEntity);

        return syncSessionId;
    }


    private ScheduleSyncResponse.SyncStats executeSyncOperation(ScheduleSyncRequest request, String syncSessionId, Long userId) {
        ScheduleSyncResponse.SyncStats stats = new ScheduleSyncResponse.SyncStats();
        stats.setAdded(0);
        stats.setUpdated(0);
        stats.setDeleted(0);
        stats.setFailed(0);

        try {
            // 1. 获取访问令牌
            String accessToken = getAccessToken(request.getAuthToken(), request.getPlatform());

            // 2. 执行同步
            performSync(request, accessToken, syncSessionId, userId, stats);

            // 3. 更新同步状态
            updateSyncStatus(syncSessionId, "SUCCESS", stats, null);

        } catch (Exception e) {
            log.error("同步失败: {}", e.getMessage(), e);
            updateSyncStatus(syncSessionId, "FAILED", stats, e.getMessage());
            throw new RuntimeException("同步失败: " + e.getMessage());
        }

        return stats;
    }

    private void performSync(ScheduleSyncRequest request, String accessToken,
                             String syncSessionId, Long userId, ScheduleSyncResponse.SyncStats stats) {
        try {
            switch (request.getSyncDirection()) {
                case IN:
                    performInboundSync(request, accessToken, userId, stats);
                    break;
                case OUT:
                    performOutboundSync(request, accessToken, userId, stats);
                    break;
                case BIDIRECTIONAL:
                    performBidirectionalSync(request, accessToken, userId, stats);
                    break;
                default:
                    throw new IllegalArgumentException("不支持的同步方向: " + request.getSyncDirection());
            }
        } catch (Exception e) {
            log.error("执行同步操作失败: {}", e.getMessage(), e);
            stats.setFailed(stats.getFailed() + 1);
            throw e;
        }
    }

    private void performInboundSync(ScheduleSyncRequest request, String accessToken,
                                    Long userId, ScheduleSyncResponse.SyncStats stats) {
        // 从外部日历同步到内部系统
        List<ExternalEvent> externalEvents = fetchExternalEvents(request, accessToken);

        for (ExternalEvent externalEvent : externalEvents) {
            try {
                // 查找是否已存在匹配的内部事件
                ScheduleEventEntity existingEvent = findMatchingInternalEvent(externalEvent, userId);

                if (existingEvent == null) {
                    // 创建新事件
                    ScheduleEventEntity newEvent = convertToInternalEvent(externalEvent, userId);
                    scheduleEventMapper.insert(newEvent);
                    stats.setAdded(stats.getAdded() + 1);
                } else if (isEventChanged(existingEvent, externalEvent)) {
                    // 更新现有事件
                    updateInternalEvent(existingEvent, externalEvent);
                    scheduleEventMapper.update(existingEvent);
                    stats.setUpdated(stats.getUpdated() + 1);
                }
            } catch (Exception e) {
                log.error("处理外部事件失败: {}", externalEvent.getId(), e);
                stats.setFailed(stats.getFailed() + 1);
            }
        }
    }

    private void performOutboundSync(ScheduleSyncRequest request, String accessToken,
                                     Long userId, ScheduleSyncResponse.SyncStats stats) {
        // 从内部系统同步到外部日历
        List<ScheduleEventEntity> internalEvents = fetchInternalEvents(request, userId);

        for (ScheduleEventEntity internalEvent : internalEvents) {
            try {
                // 查找匹配的外部事件
                ExternalEvent externalEvent = findMatchingExternalEvent(internalEvent, accessToken, request.getPlatform());

                if (externalEvent == null) {
                    // 创建外部事件
                    ExternalEvent newExternalEvent = convertToExternalEvent(internalEvent);
                    createExternalEvent(newExternalEvent, accessToken, request.getPlatform());
                    stats.setAdded(stats.getAdded() + 1);
                } else if (isEventChanged(internalEvent, externalEvent)) {
                    // 更新外部事件
                    updateExternalEvent(externalEvent, internalEvent, accessToken, request.getPlatform());
                    stats.setUpdated(stats.getUpdated() + 1);
                }
            } catch (Exception e) {
                log.error("同步内部事件到外部失败: {}", internalEvent.getId(), e);
                stats.setFailed(stats.getFailed() + 1);
            }
        }
    }

    private void performBidirectionalSync(ScheduleSyncRequest request, String accessToken,
                                          Long userId, ScheduleSyncResponse.SyncStats stats) {
        // 双向同步需要处理冲突解决
        performInboundSync(request, accessToken, userId, stats);
        performOutboundSync(request, accessToken, userId, stats);
    }

    private ScheduleEventEntity findMatchingInternalEvent(ExternalEvent externalEvent, Long userId) {
        // 根据外部事件ID查找匹配的内部事件
        QueryWrapper queryWrapper = QueryWrapper.create()
                .where("external_id = ?", externalEvent.getId())
                .and("creator_id = ?", userId);

        return scheduleEventMapper.selectOneByQuery(queryWrapper);
    }

    private boolean isEventChanged(ScheduleEventEntity internalEvent, ExternalEvent externalEvent) {
        // 比较事件是否发生变化
        return !Objects.equals(internalEvent.getTitle(), externalEvent.getTitle()) ||
                !Objects.equals(internalEvent.getStartTime(), externalEvent.getStartTime()) ||
                !Objects.equals(internalEvent.getEndTime(), externalEvent.getEndTime()) ||
                !Objects.equals(internalEvent.getLocation(), externalEvent.getLocation());
    }

    private boolean isEventChanged(ExternalEvent externalEvent, ScheduleEventEntity internalEvent) {
        // 比较事件是否发生变化
        return !Objects.equals(externalEvent.getTitle(), internalEvent.getTitle()) ||
                !Objects.equals(externalEvent.getStartTime(), internalEvent.getStartTime()) ||
                !Objects.equals(externalEvent.getEndTime(), internalEvent.getEndTime()) ||
                !Objects.equals(externalEvent.getLocation(), internalEvent.getLocation());
    }

    private ScheduleEventEntity convertToInternalEvent(ExternalEvent externalEvent, Long userId) {
        ScheduleEventEntity internalEvent = new ScheduleEventEntity();
        internalEvent.setTitle(externalEvent.getTitle());
        internalEvent.setStartTime(externalEvent.getStartTime());
        internalEvent.setEndTime(externalEvent.getEndTime());
        internalEvent.setLocation(externalEvent.getLocation());
        internalEvent.setCreatorId(userId);
        internalEvent.setCreateTime(new Date());
        internalEvent.setUpdateTime(new Date());
        internalEvent.setStatus(EventStatus.ACTIVE);
        // 设置事件类型
        if (externalEvent.getEventType() != null) {
            internalEvent.setType(EventType.getByName(externalEvent.getEventType()));
        } else {
            internalEvent.setType(EventType.OTHER);
        }
        return internalEvent;
    }

    private ExternalEvent convertToExternalEvent(ScheduleEventEntity internalEvent) {
        ExternalEvent externalEvent = new ExternalEvent();
        externalEvent.setTitle(internalEvent.getTitle());
        externalEvent.setStartTime(internalEvent.getStartTime());
        externalEvent.setEndTime(internalEvent.getEndTime());
        externalEvent.setLocation(internalEvent.getLocation());
        if (internalEvent.getType() != null) {
            externalEvent.setEventType(internalEvent.getType().getName());
        }
        return externalEvent;
    }

    private void updateInternalEvent(ScheduleEventEntity internalEvent, ExternalEvent externalEvent) {
        internalEvent.setTitle(externalEvent.getTitle());
        internalEvent.setStartTime(externalEvent.getStartTime());
        internalEvent.setEndTime(externalEvent.getEndTime());
        internalEvent.setLocation(externalEvent.getLocation());
        internalEvent.setUpdateTime(new Date());
        // 更新事件类型
        if (externalEvent.getEventType() != null) {
            internalEvent.setType(EventType.getByName(externalEvent.getEventType()));
        }
    }

    private ExternalEvent findMatchingExternalEvent(ScheduleEventEntity internalEvent,
                                                    String accessToken, PlatformEnum platform) {
        // 根据内部事件查找匹配的外部事件
        // 实际实现应调用相应平台的API
        return null;
    }

    private void createExternalEvent(ExternalEvent externalEvent, String accessToken, PlatformEnum platform) {
        // 调用相应平台的API创建事件
        log.info("在{}平台创建事件: {}", platform.getName(), externalEvent.getTitle());
    }

    private void updateExternalEvent(ExternalEvent externalEvent, ScheduleEventEntity internalEvent,
                                     String accessToken, PlatformEnum platform) {
        // 调用相应平台的API更新事件
        log.info("在{}平台更新事件: {}", platform.getName(), externalEvent.getId());
    }

    private List<ExternalEvent> fetchExternalEvents(ScheduleSyncRequest request, String accessToken) {
        // 根据平台类型调用相应的API获取事件
        // 这里返回模拟数据
        return new ArrayList<>();
    }

    private List<ScheduleEventEntity> fetchInternalEvents(ScheduleSyncRequest request, Long userId) {
        // 获取需要同步的内部事件
        QueryWrapper queryWrapper = QueryWrapper.create()
                .where("creator_id = ?", userId)
                .and("status = ?", "ACTIVE");

        // 应用过滤条件
        if (request.getSyncFilters() != null) {
            ScheduleSyncRequest.SyncFilters filters = request.getSyncFilters();

            // 按日期范围过滤
            if (filters.getDateRange() != null) {
                ScheduleSyncRequest.SyncFilters.DateRange dateRange = filters.getDateRange();
                if (dateRange.getStart() != null) {
                    queryWrapper.and("start_time >= ?", dateRange.getStart());
                }
                if (dateRange.getEnd() != null) {
                    queryWrapper.and("end_time <= ?", dateRange.getEnd());
                }
            }
        }

        return scheduleEventMapper.selectListByQuery(queryWrapper);
    }

    private String getAccessToken(String authCode, PlatformEnum platform) {
        // 根据授权码获取访问令牌
        // 实际实现应调用OAuth2授权服务器
        log.info("获取{}平台访问令牌", platform.getName());
        return "access_token_" + System.currentTimeMillis();
    }

    private String calculateNextSyncTime() {
        // 计算下次同步时间（30分钟后）
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, 30);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        return sdf.format(calendar.getTime());
    }

    private void updateSyncStatus(String syncSessionId, String status, ScheduleSyncResponse.SyncStats stats, String errorMessage) {
        ScheduleSyncEntity syncEntity = scheduleSyncMapper.findBySessionId(syncSessionId);

        if (syncEntity != null) {
            syncEntity.setLastSyncStatus(status);
            syncEntity.setLastSyncTime(new Date());

            scheduleSyncMapper.update(syncEntity);
        }
    }

    // 工具方法：加密令牌
    private String encryptToken(String token) {
        // 实际实现应使用加密算法
        return Base64.getEncoder().encodeToString(token.getBytes());
    }

    // 工具方法：解密令牌
    private String decryptToken(String encryptedToken) {
        // 实际实现应使用解密算法
        return new String(Base64.getDecoder().decode(encryptedToken));
    }




}